package com.box2dwrapper.view.core
{
	import Box2D.Dynamics.b2Body;
	import Box2D.Dynamics.b2World;
	
	import com.box2dwrapper.manager.DragManager;
	import com.box2dwrapper.manager.Input;
	
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.Event;

	public class AbstractView extends MovieClip implements IView
	{
		public static const SCALE:Number = 30;
		public static const TIME_STEP:Number = 0.06;
		public static const ITERATIONS:Number = 10;
		
		protected var _world:b2World;
		protected var _height:Number;
		protected var _width:Number;
		protected var _sleep:Boolean;
		protected var _hForce:Number;
		protected var _vForce:Number;
		protected var _physicsContainer:Sprite;
		protected var _inputController:Input
		
		public function AbstractView()
		{
			super();
			_physicsContainer = new Sprite();
			addChild(_physicsContainer);
			_inputController = new Input(_physicsContainer);
		}
		
		public function singlePhysicsRender():void
		{
			handleRenderRequest()
		}
		
		public function startPhysicsRender():void
		{
			addEventListener(Event.ENTER_FRAME, handleRenderRequest);
		}
		
		public function stopPhysicsRender():void
		{
			removeEventListener(Event.ENTER_FRAME, handleRenderRequest);
		}
		
		public function get world():b2World{ return _world }
		public function set world(worldObject:b2World):void{ _world = worldObject; }
		
		public function get worldWidth():Number { return _width; }
		public function set worldWidth(wWidth:Number):void { _width = wWidth; }
		
		public function get worldHeight():Number { return _height; }
		public function set worldHeight(wHeight:Number):void { _height = wHeight; }
		
		public function get sleep():Boolean { return _sleep; }
		public function set sleep(wSleep:Boolean):void { _sleep = wSleep; }
		
		public function get horizontalForce():Number { return _hForce; }
		public function set horizontalForce(hForce:Number):void { _hForce = hForce; }
		
		public function get verticalForce():Number { return _vForce; }
		public function set verticalForce(vForce:Number):void { _vForce = vForce; }
		
		public function get physicsContainer():Sprite { return _physicsContainer; }
		
		public function handleRenderRequest(e:Event = null):void
		{
			world.Step(AbstractView.TIME_STEP, AbstractView.ITERATIONS);
			
			if(DragManager.allowDrag){
				DragManager.updateMouseWorld();
				DragManager.mouseDrag();
			}
			
			for (var bb:b2Body = world.m_bodyList; bb; bb = bb.m_next){
				if (bb.m_userData is DisplayObject){
					bb.m_userData = bb.m_userData as DisplayObject;
					bb.m_userData.x = bb.GetPosition().x * AbstractView.SCALE;
					bb.m_userData.y = bb.GetPosition().y * AbstractView.SCALE;
					bb.m_userData.rotation = bb.GetAngle() * (180/Math.PI);
				}
			}
			
			Input.update();
		}
		
	}
}